This is an R Markdown Notebook. When you execute code within the notebook, the results appear beneath the code.
Try executing this chunk by clicking the Run button within the chunk or by placing your cursor inside it and pressing Ctrl+Shift+Enter.
Add a new chunk by clicking the Insert Chunk button on the toolbar or by pressing Ctrl+Alt+I.
When you save the notebook, an HTML file containing the code and output will be saved alongside it (click the Preview button or press Ctrl+Shift+K to preview the HTML file).
The preview shows you a rendered HTML copy of the contents of the editor. Consequently, unlike Knit, Preview does not run any R code chunks. Instead, the output of the chunk when it was last run in the editor is displayed.
setwd("D:/R program")
The working directory was changed to D:/R program inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the working directory for notebook chunks.
#values needed
K= 1.38064852*(10)^-23 #m2 kg/ s2 K boltzmann constant
mu= 1.126*(10)^-3 #kg/m s dynamic viscosity in 18C
v= 1.099*(10)^-6 #m2/s kinematic viscosity in 18C
Reh_calc= 2.3E-6 #in m radius Ehux
Reh_naked= 1.8E-6 #in m radius Ehux
Rehv= 90*(10)^-9 #in m radius virus
Temp = 18+273.15 #temp in kelvin, here assuming 18C
Den_OcM = 1.05 #g/cm3 density organic cell matter
Den_CH2O= 1.025 #g/cm3 density seawater at 18C
hostnum <- (10)^3
virnum <- (10)^4
require (ggplot2)
require(plotly)
require(grid)
require(ggthemes)
require (dplyr)
require(plyr)
source ("theme_Publication.R")
source("resizewin.R")
resize.win(12,9)
Error in dev.off() : cannot shut down device 1 (the null device)
for Brownian motion
#Brownian motion (BM)
#1. make a data frame
BM <- data.frame (group= c("naked", "calcified"), rad= c(1.8E-6, 2.3E-6))
#2. calculate beta (beta)
BM$beta_s <- (2*(K*(10)^4)*Temp*(((BM$rad+Rehv)*100)^2))/((3*mu*10)*(BM$rad*Rehv*1e4)) #m3/s
BM$beta_d <- BM$beta_s*86400 #to cm3/day
# go back to this later
#3. calculate encounters (E)
BM$E <- BM$beta_d*hostnum
BM$E_HV <- BM$beta_d*virnum*hostnum
BM
Differential settling (DS)
#Differential settling (DS)
#1. read in PIC data
library(readr) #always use readr not baseR
setwd("D:/R program")
The working directory was changed to D:/R program inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the working directory for notebook chunks.
PIC <- read_csv("Postdoc-R/CSV Files/PIC.csv")
Parsed with column specification:
cols(
Strain = col_character(),
Replicate = col_integer(),
TC = col_double(),
AC = col_double(),
Cellcount = col_double()
)
PIC$Strain <- as.factor(PIC$Strain)
PIC$Replicate <- as.factor(PIC$Replicate)
#certain changes in data.table API made calculating inside the list data.table to not work
#2. calculate PIC
PIC$PIC <- PIC$TC-PIC$AC
PIC$PICpercell <- (PIC$PIC/PIC$Cellcount)*(10)^-3#in g
PIC$PICpercellpg <- PIC$PICpercell*1e12
ggplotly(ggplot(data=PIC, aes(x=Strain, y=PICpercellpg)) + geom_boxplot()+geom_point(size=2) +theme_Publication())
#3. calculate density of cells (den)
PIC <- mutate(PIC, group = ifelse(PICpercellpg < 4 , "naked", "calcified"))
ggplotly(ggplot(data=PIC, aes(x=group, y=PICpercellpg)) + geom_boxplot()+geom_point(size=2, aes(color=Strain))+
theme_Publication())
plotly.js does not (yet) support horizontal legend items
You can track progress here:
https://github.com/plotly/plotly.js/issues/53
PIC <- mutate(PIC, rad = ifelse(group == "naked" , 1.8E-6, 2.3E-6)) #in m
PIC$volume <- (4/3)*pi*(PIC$rad*100)^3 #in cm3
PIC$Den_cell <- PIC$PICpercell/PIC$volume #g/cm3
PIC$Den_celltotal <- PIC$Den_cell+Den_OcM
ggplotly(ggplot(data=PIC, aes(x=Strain, y=Den_celltotal, color=group)) + geom_boxplot()+geom_point(size=2)
+theme_Publication())
plotly.js does not (yet) support horizontal legend items
You can track progress here:
https://github.com/plotly/plotly.js/issues/53
#some strains that are "naked" have PIC<2. I chose to ignore this since in the lm model I do not use
#strain as a factor, rather data is treated as a whole (e.g., no grouping)
#4. calculate sinking velocity of cells
PIC$SinkVel <- ((2*((PIC$rad*100)^2)*(981)*(PIC$Den_celltotal-Den_CH2O))/(9*(mu*10)))*864 #meter per day
#g is converted to per day, 864 is the one that converts cm/s to m/day
#plot sinking velocity vs calcification
ggplot(data=PIC, aes(x=PICpercellpg, y=SinkVel, color=Strain, shape=group)) + geom_point(size=5)+theme_Publication()+
labs(y = expression("Sinking velocity"~("m"~day^-1)), x = expression("PIC"~cell^-1)) +
scale_y_log10(
breaks = scales::trans_breaks("log10", function(x) 10^x, n=2),
labels = scales::trans_format("log10", scales::math_format(10^.x))) + annotation_logticks(sides="l")

#5. calculate sinkvel of viruses
Den_virus <- 1.09 #data from Ben D. fresh EhV-207 density. old density of EhV-207 is 1.19
Ehv_SinkVel <- ((2*((Rehv*100)^2)*(981)*(Den_virus-Den_CH2O))/(9*(mu*10)))*864 #equals to 0
#6. calculate beta kernels
PIC$beta_s <- pi*(((PIC$rad+Rehv)*100)^2)*(abs((PIC$SinkVel-Ehv_SinkVel)/864)) #in encounters cm3/s
PIC$beta_d <- PIC$beta_s*86400 #in cm3/day
Sinkvelbeta.plot<- ggplot(data=PIC, aes(x=SinkVel, y=beta_d, color=Strain, shape=group)) + geom_point(size=5)+
theme_Publication()+
labs(x = expression("Sinking velocity"~("m"~day^-1)), y = expression(beta~("Encounters" ~ cm^3~day^-1))) +
scale_y_log10(
breaks = scales::trans_breaks("log10", function(x) 10^x, n=2),
labels = scales::trans_format("log10", scales::math_format(10^.x))) + annotation_logticks(sides="l")
Sinkvelbeta.plot #change ticks

ggplotly(Sinkvelbeta.plot)
geom_GeomLogticks() has yet to be implemented in plotly.
If you'd like to see this geom implemented,
Please open an issue with your example code at
https://github.com/ropensci/plotly/issuesplotly.js does not (yet) support horizontal legend items
You can track progress here:
https://github.com/plotly/plotly.js/issues/53
ggplotly(ggplot(data=PIC, aes(x=Strain, y=SinkVel)) + geom_boxplot()+theme_Publication())
ggplot(data=PIC, aes(x=PICpercellpg, y=beta_d, color=Strain)) + geom_point(size=5)+theme_Publication()+
labs(y = expression(beta~("Encounters"~cm^3~day^-1)), x = expression("PIC"~cell^-1)) +
scale_y_log10(
breaks = scales::trans_breaks("log10", function(x) 10^x, n=2),
labels = scales::trans_format("log10", scales::math_format(10^.x))) + annotation_logticks(sides="l")

#7. calculate beta and encounters
#beta are in cells cm3/ day then encounters are to cells/cm3 day
PIC$E_DS_HV <- (PIC$beta_d*virnum*hostnum) #E calculated with Virus and Host (10:1 MOI)
PIC$E_DS_V <- (PIC$beta_d*virnum) #E calculated with Virus
#8. calculate for lith parameters
lithvol <- 3*1e-12 #in cm3, from CJ's paper
PIC$perlith <- PIC$PICpercell/20 #in g, assuming 20 liths attached
PIC$perlithpg <- PIC$perlith*1e12 #in pg
PIC$Denlith <- (PIC$perlith/lithvol) + Den_OcM #in g/cm3, with organic matter attached
rad_lith <- 2E-6 #in m radius
PIC$SinkVel_lith <- ((2*((rad_lith*100)^2)*(981)*(PIC$Denlith-Den_CH2O))/(9*(mu*10)))*864 #meter per day
PIC$beta_s_lith <- pi*(((rad_lith+Rehv)*100)^2)*(abs((PIC$SinkVel_lith-Ehv_SinkVel)/864)) #in encounters cm3/s
PIC$beta_d_lith <- PIC$beta_s_lith*86400 #in cm3/day
ggplot(data=PIC, aes(x=perlithpg, y=SinkVel_lith, color=Strain, shape=group)) + geom_point(size=5)+theme_Publication()+
labs(y = expression("Sinking velocity"~("m"~day^-1)), x = expression("PIC"~lith^-1))

PIC$Elith_DS_HV <- (PIC$beta_d_lith*virnum*hostnum) #E calculated with Virus and Host (10:1 MOI)
PIC$Elith_DS_V <- (PIC$beta_d_lith*virnum) #E calculated with Virus
require (dplyr)
PIC$group2 <- case_when(
PIC$PICpercellpg <2 ~ "naked_bouyant",
PIC$PICpercellpg >2 & PIC$PICpercellpg < 4 ~ "naked/calcified uncertain",
PIC$PICpercellpg >4 & PIC$PICpercellpg < 10 ~ "moderately calcified",
PIC$PICpercellpg >10 ~ "strongly calcified",
TRUE ~ as.character(PIC$PICpercellpg)
)
breaks <- 10^(-10:10)
ggplot(data=PIC, aes(x=SinkVel, y=E_DS_HV, color=Strain, shape=group)) + geom_point(size=5)+theme_Publication()+
scale_y_log10(
breaks = scales::trans_breaks("log10", function(x) 10^x, n=2),
labels = scales::trans_format("log10", scales::math_format(10^.x))) + annotation_logticks(sides="l")

ggplot(data=PIC, aes(x=SinkVel, y=E_DS_V, color=Strain, shape=group)) + geom_point(size=5)+theme_Publication()+
scale_y_log10(
breaks = scales::trans_breaks("log10", function(x) 10^x, n=2),
labels = scales::trans_format("log10", scales::math_format(10^.x))) + annotation_logticks(sides="l")

ggplot(data=PIC, aes(x=SinkVel_lith, y=Elith_DS_V, color=Strain, shape=group)) + geom_point(size=5) +
theme_Publication() + scale_y_log10(
breaks = scales::trans_breaks("log10", function(x) 10^x, n=3),
labels = scales::trans_format("log10", scales::math_format(10^.x))) + annotation_logticks(sides="l")

summary_DS <- ddply(PIC, .(Strain), summarize, PICpercellpg=mean(PICpercellpg), perlithpg = mean(perlithpg),
Den_celltotal = mean (Den_celltotal),
SinkVel=mean(SinkVel),beta_d=mean(beta_d), E_DS_V= mean(E_DS_V), E_DS_HV=mean(E_DS_HV),
SinkVel_lith=mean (SinkVel_lith), beta_d_lith=mean (beta_d_lith), Elith_DS_HV=mean (Elith_DS_HV),
Elith_DS_V=mean (Elith_DS_V))
summary_DS_bygroup <- ddply(PIC, .(group2), summarize, PICpercellpg=mean(PICpercellpg), perlithpg = mean(perlithpg),
Den_celltotal = mean (Den_celltotal),
SinkVel=mean(SinkVel),beta_d=mean(beta_d), E_DS_V= mean(E_DS_V), E_DS_HV=mean(E_DS_HV),
SinkVel_lith=mean (SinkVel_lith), beta_d_lith=mean (beta_d_lith),
Elith_DS_HV=mean (Elith_DS_HV), Elith_DS_V=mean (Elith_DS_V))
summary_DS
summary_DS_bygroup
setwd("D:/R program")
The working directory was changed to D:/R program inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the working directory for notebook chunks.
require(openxlsx)
write.xlsx(summary_DS, file = "Postdoc-R/Exported Tables/summary_DS.xlsx")
write.xlsx(summary_DS_bygroup, file = "Postdoc-R/Exported Tables/summary_DS_bygroup.xlsx")
#9. regression of PIC and sinkvel of cells and liths
#a. for cells
PIC_reg <- lm(SinkVel~PICpercellpg, data=PIC) #essentially perfect fit: summary may be unreliable haha
summary(PIC_reg)
Call:
lm(formula = SinkVel ~ PICpercellpg, data = PIC)
Residuals:
Min 1Q Median 3Q Max
-0.0115036 -0.0029329 0.0004329 0.0021756 0.0113796
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 0.0180085 0.0009620 18.72 <2e-16 ***
PICpercellpg 0.0177476 0.0001254 141.58 <2e-16 ***
---
Signif. codes: 0 *** 0.001 ** 0.01 * 0.05 . 0.1 1
Residual standard error: 0.005175 on 44 degrees of freedom
Multiple R-squared: 0.9978, Adjusted R-squared: 0.9978
F-statistic: 2.004e+04 on 1 and 44 DF, p-value: < 2.2e-16
plot(residuals.lm(PIC_reg))
layout(matrix(1:4,2,2))

plot(PIC_reg)

coef(PIC_reg)
(Intercept) PICpercellpg
0.01800852 0.01774764
# coef(PIC_reg)
#(Intercept) PICpercellpg
#0.01800852 0.01774764
cor(PIC$PICpercellpg, PIC$SinkVel)
[1] 0.9989042
#cor = 0.9989042
beta_reg <- lm(beta_d~PICpercellpg, data=PIC)
plot(residuals.lm(beta_reg))
coef(beta_reg)
(Intercept) PICpercellpg
1.639233e-07 3.243054e-07
#coef(beta_reg)
# (Intercept) PICpercellpg
#1.639233e-07 3.243054e-07
E_DS_HV_reg <- lm(E_DS_HV~PICpercellpg, data=PIC)
E_DS_V_reg <- lm(E_DS_V~PICpercellpg, data=PIC)
plot(residuals.lm(E_DS_HV_reg))
plot(residuals.lm(E_DS_V_reg))
coef(E_DS_HV_reg)
(Intercept) PICpercellpg
1.639233 3.243054
coef(E_DS_V_reg)
(Intercept) PICpercellpg
0.001639233 0.003243054
#b. for liths
perlith_reg <- lm (perlithpg~PICpercellpg, data=PIC)
plot(resid(perlith_reg))

coef(perlith_reg)
(Intercept) PICpercellpg
-6.547738e-17 5.000000e-02
sinkvel_lith_reg <- lm(SinkVel_lith~PICpercellpg, data = PIC)
summary(sinkvel_lith_reg)
essentially perfect fit: summary may be unreliable
Call:
lm(formula = SinkVel_lith ~ PICpercellpg, data = PIC)
Residuals:
Min 1Q Median 3Q Max
-1.043e-16 -3.686e-17 -2.422e-18 4.040e-17 7.364e-17
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 1.673e-02 8.512e-18 1.965e+15 <2e-16 ***
PICpercellpg 1.115e-02 1.109e-18 1.005e+16 <2e-16 ***
---
Signif. codes: 0 *** 0.001 ** 0.01 * 0.05 . 0.1 1
Residual standard error: 4.579e-17 on 44 degrees of freedom
Multiple R-squared: 1, Adjusted R-squared: 1
F-statistic: 1.011e+32 on 1 and 44 DF, p-value: < 2.2e-16
plot(residuals.lm(sinkvel_lith_reg))
layout(matrix(1:4,2,2))

plot(sinkvel_lith_reg)

coef(sinkvel_lith_reg)
(Intercept) PICpercellpg
0.01672753 0.01115169
beta_lith_reg <- lm(beta_d_lith~PICpercellpg, data=PIC)
plot(residuals.lm(beta_lith_reg))
coef(beta_lith_reg)
(Intercept) PICpercellpg
2.302277e-07 1.528542e-07
Elith_DS_HV_reg <- lm(Elith_DS_HV~PICpercellpg, data=PIC)
Elith_DS_V_reg <- lm(Elith_DS_V~PICpercellpg, data=PIC)
plot(residuals.lm(Elith_DS_HV_reg))
plot(residuals.lm(Elith_DS_V_reg))

coef(Elith_DS_HV_reg)
(Intercept) PICpercellpg
2.302277 1.528542
coef(Elith_DS_V_reg)
(Intercept) PICpercellpg
0.002302277 0.001528542
# 9. make new dataframe depending on experimental PIC values
# make a prediction based on PIC values
require(truncnorm)
require(Rmisc)
summary(PIC$PICpercellpg)
Min. 1st Qu. Median Mean 3rd Qu. Max.
-1.5873 0.5523 2.3009 4.6739 6.1204 20.1442
summarySE(data=PIC, measurevar="PICpercellpg")
PIC_newdata <- as.data.frame(rtruncnorm(n=1000, a=-1.6, b=20.14, mean=4.7, sd=6.15))
#rename column. rename function in plyr
library(plyr)
PIC_newdata <- rename (PIC_newdata, c ("rtruncnorm(n = 1000, a = -1.6, b = 20.14, mean = 4.7, sd = 6.15)" =
"PICpercellpg"))
PIC_newdata <- mutate(PIC_newdata, group = ifelse(PICpercellpg < 4 , "naked", "calcified"))
ggplotly(ggplot(data=PIC_newdata, aes(x=group, y=PICpercellpg)) + geom_boxplot()+geom_point(size=2) +
theme_Publication())
PIC_newdata$group2 <- case_when(
PIC_newdata$PICpercellpg <2 ~ "naked_bouyant",
PIC_newdata$PICpercellpg >2 & PIC_newdata$PICpercellpg < 4 ~ "naked/calcified uncertain",
PIC_newdata$PICpercellpg >4 & PIC_newdata$PICpercellpg < 10 ~ "moderately calcified",
PIC_newdata$PICpercellpg >10 ~ "strongly calcified",
TRUE ~ as.character(PIC_newdata$PICpercellpg)
)
ggplotly(ggplot(data=PIC_newdata, aes(x=group2, y=PICpercellpg)) +
geom_boxplot()+geom_point(size=2) +theme_Publication())
#a. for host
PIC_newdata$SinkVel.pred <- predict(PIC_reg, data.frame(PIC_newdata))
PIC_newdata_reg <- lm(SinkVel.pred~PICpercellpg, data=PIC_newdata)
coef(PIC_newdata_reg)
(Intercept) PICpercellpg
0.01800852 0.01774764
#same coef as PIC_reg
#> coef(PIC_newdata_reg)
#(Intercept) PICpercellpg
#0.01800852 0.01774764
plot(resid(PIC_newdata_reg))

ggplot(data=PIC_newdata, aes(x=PICpercellpg, y=SinkVel.pred)) +geom_point(size=2) +theme_Publication()+
labs(y = expression("Predicted Sinking velocity"~("m"~day^-1)), x = expression("PIC"~cell^-1))

PIC_newdata$beta.pred <- predict(beta_reg, data.frame(PIC_newdata))
PIC_newdata$E_DS_V.pred <- predict(E_DS_V_reg, data.frame(PIC_newdata))
PIC_newdata$E_DS_HV.pred <- predict(E_DS_HV_reg, data.frame(PIC_newdata))
ggplot(data=PIC_newdata, aes(x=PICpercellpg, y=E_DS_V.pred)) +geom_point(size=5, aes(color=group2)) +
theme_Publication() + geom_smooth() +
scale_y_log10(
breaks = scales::trans_breaks("log10", function(x) 10^x, n=4),
labels = scales::trans_format("log10", scales::math_format(10^.x))) + annotation_logticks(sides="l")

PICbeta_new <- ggplot(data=PIC_newdata, aes(x=PICpercellpg, y=beta.pred)) +
geom_point(size=5, aes(color=PICpercellpg))+
scale_colour_gradient(name="PIC", guide=guide_colorbar(direction = "vertical", barheight=10))+
theme_Publication() +
scale_y_log10(
breaks = scales::trans_breaks("log10", function(x) 10^x, n=4),
labels = scales::trans_format("log10", scales::math_format(10^.x))) + annotation_logticks(sides="l") +
labs(y = expression(beta~("Predicted Encounters"~cm^3~day^-1)), x = expression("PIC"~cell^-1))+
theme(legend.position = "right")
PICbeta_new

#b. for liths
PIC_newdata$perlithpg.pred <- predict(perlith_reg, data.frame(PIC_newdata))
PIC_newdata$SinkVel.pred.lith <- predict(sinkvel_lith_reg, data.frame(PIC_newdata))
sinkvel_lith_reg.pred <- lm(SinkVel.pred.lith~PICpercellpg, data=PIC_newdata)
coef(sinkvel_lith_reg.pred)
(Intercept) PICpercellpg
0.01672753 0.01115169
#same coef as sinkvel_lith_reg
#> coef(sinkvel_lith_reg.pred)
#(Intercept) PICpercellpg
# 0.01672753 0.01115169
plot(resid(sinkvel_lith_reg.pred))

ggplot(data=PIC_newdata, aes(x=perlithpg.pred, y=SinkVel.pred.lith)) +geom_point(size=2) +theme_Publication()+
labs(y = expression("Predicted Sinking velocity of Liths"~("m"~day^-1)), x = expression("PIC"~lith^-1))

PIC_newdata$beta.pred.lith <- predict(beta_lith_reg, data.frame(PIC_newdata))
PIC_newdata$E_DS_V.pred.lith <- predict(Elith_DS_HV_reg, data.frame(PIC_newdata))
PIC_newdata$E_DS_HV.pred.lith <- predict(Elith_DS_HV_reg, data.frame(PIC_newdata))
ggplot(data=PIC_newdata, aes(x=perlithpg.pred, y=E_DS_V.pred.lith)) +geom_point(size=5, aes(color=group2)) +
theme_Publication() + scale_y_log10(
breaks = scales::trans_breaks("log10", function(x) 10^x, n=4),
labels = scales::trans_format("log10", scales::math_format(10^.x))) + annotation_logticks(sides="l")+ geom_smooth()

PICbeta_new.lith <- ggplot(data=PIC_newdata, aes(x=perlithpg.pred, y=beta.pred.lith)) +
geom_point(size=5, aes(color=PICpercellpg))+
scale_colour_gradient(name="PIC", guide=guide_colorbar(direction = "vertical", barheight=10))+
theme_Publication() +
scale_y_log10(
breaks = scales::trans_breaks("log10", function(x) 10^x, n=4),
labels = scales::trans_format("log10", scales::math_format(10^.x))) + annotation_logticks(sides="l") +
labs(y = expression(beta~("Predicted Encounters of lith " ~cm^3~day^-1)), x = expression("PIC"~lith^-1))+
theme(legend.position = "right")
PICbeta_new.lith

#summaries
summary_DS_newdata_bygroup2 <- ddply(PIC_newdata, .(group2), summarize, PICpercellpg=mean(PICpercellpg), SinkVel.pred=mean(SinkVel.pred),beta.pred= mean (beta.pred), E_DS_V.pred= mean(E_DS_V.pred), E_DS_HV.pred=mean(E_DS_HV.pred))
summary_DS_bygroup.pred <- ddply(PIC_newdata, .(group2), summarize, PICpercellpg=mean(PICpercellpg),
perlithpg.pred = mean(perlithpg.pred), SinkVel.pred=mean(SinkVel.pred),
beta.pred= mean (beta.pred), E_DS_V.pred= mean(E_DS_V.pred),
E_DS_HV.pred=mean(E_DS_HV.pred),
SinkVel.pred.lith=mean(SinkVel.pred.lith),beta.pred.lith= mean (beta.pred.lith),
E_DS_V.pred.lith= mean(E_DS_V.pred.lith), E_DS_HV.pred.lith=mean(E_DS_HV.pred.lith))
summary_DS_bygroup.pred
write.xlsx(summary_DS_bygroup.pred, file = "Postdoc-R/Exported Tables/summary_DS_bygroup.pred.xlsx")
cannot create file 'Postdoc-R/Exported Tables/summary_DS_bygroup.pred.xlsx', reason 'No such file or directory'
turbulence
#TURBULENCE
#disrate is cm2/s3
#make data frame
disrate <- rep_len(10^(-8:-2), length.out=14)
calc <- rep_len(c("calcified"), length.out=7)
naked <- rep_len(c("naked"), length.out=7)
lith <- rep_len(c("lith"), length.out=7)
group <- c(calc, naked, lith)
turb <- as.data.frame(cbind(disrate, group))
number of rows of result is not a multiple of vector length (arg 1)
turb$rad <- case_when(
turb$group =="naked" ~ 1.8E-6,
turb$group =="calcified" ~ 2.3E-6,
turb$group =="lith" ~ 2E-6,
TRUE ~ as.numeric(turb$group)
)
#turb <- mutate(turb, rad = ifelse(group == "naked" , 1.8E-6, 2.3E-6)) #in m
turb$disrate <- as.numeric(as.character(turb$disrate))
turb$Kol <- ((v^3/turb$disrate)^0.25)*100 #Kolmogorov length scale in cm
#everything is below 1 cm, use eqn 2 in TK
turb$beta_d <- (4.2*pi*((turb$disrate/(v*100^2))^0.5)*(((turb$rad+Rehv)*100)^3))*86400
turb$beta_Heidi <- (0.42*pi*((turb$disrate/(v*100^2))^0.5)*(((turb$rad+Rehv)*100)^3))*86400
#check encounters
#use TK, in cm3 s
turb$E_turb_HV <- (turb$beta_d*hostnum*virnum) #E calculated with Virus and Host (10:1 MOI)
turb$E_turb_V <- (turb$beta_d*virnum) #E calculated with virus only
#breaks <- 10^(-10:10)
#minor_breaks <- rep(1:9, 21)*(10^rep(-10:10, each=9))
ggplot(data = turb, aes(x = disrate, y = beta_d, color=group)) + geom_point(size =5) +
scale_y_log10(
breaks = scales::trans_breaks("log10", function(x) 10^x, n=4),
labels = scales::trans_format("log10", scales::math_format(10^.x))) +
scale_x_log10(
breaks = scales::trans_breaks("log10", function(x) 10^x, n=4),
labels = scales::trans_format("log10", scales::math_format(10^.x))) +
annotation_logticks() +
theme_Publication()

library(scales)
ggplot(data = turb, aes(x = disrate, y = E_turb_V, color=group)) + geom_point(size =5) +
scale_y_log10(
breaks = scales::trans_breaks("log10", function(x) 10^x, n=4),
labels = scales::trans_format("log10", scales::math_format(10^.x))) +
scale_x_log10(
breaks = scales::trans_breaks("log10", function(x) 10^x, n=4),
labels = scales::trans_format("log10", scales::math_format(10^.x))) +
annotation_logticks()+
theme_Publication()

add beta kernels and plot
#extract mean betas from PIC_newdata
beta_DS <- summarySE (PIC_newdata, measurevar = "beta.pred", groupvars = c("group", "group2"))
lith_DS <-summarySE (PIC_newdata, measurevar = "beta.pred.lith", groupvars = c("group", "group2"))
all <- Reduce(function(x,y) merge(x,y,by="group",all=TRUE) ,list(BM, beta_DS, lith_DS, turb))
#beta_d.x=BM, beta.pred=DS, betapred.lith= beta.pred.lith, beta_d.y=turb
#rename beta.pred to beta_pred so I can use grep.
#all <- rename (all, c("beta_d.x" = "beta_BM", "beta.pred" = "beta_DS", "beta_d.y" = "beta_turb"))
library(data.table)
NT = data.table(all, key="group")
allbetas = NT[, list(group=group, disrate=disrate, beta_BM=beta_d.x, beta_DS=beta.pred, beta_turb = beta_d.y,
beta_BM_DS =beta_d.x + beta.pred,
beta_DS_turb = beta.pred + beta_d.y,
beta_DS_turb.lith = beta.pred.lith + beta_d.y,
beta_BM_turb = beta_d.x + beta_d.y,
beta_all = beta_d.x + beta_d.y + beta.pred),
by=c("group2")]
Error in eval(bysub, x, parent.frame()) : object 'group2' not found
LS0tDQp0aXRsZTogImJldGEga2VybmVsIGZpbmFsIG5vdGVib29rIg0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCg0KVGhpcyBpcyBhbiBbUiBNYXJrZG93bl0oaHR0cDovL3JtYXJrZG93bi5yc3R1ZGlvLmNvbSkgTm90ZWJvb2suIFdoZW4geW91IGV4ZWN1dGUgY29kZSB3aXRoaW4gdGhlIG5vdGVib29rLCB0aGUgcmVzdWx0cyBhcHBlYXIgYmVuZWF0aCB0aGUgY29kZS4gDQoNClRyeSBleGVjdXRpbmcgdGhpcyBjaHVuayBieSBjbGlja2luZyB0aGUgKlJ1biogYnV0dG9uIHdpdGhpbiB0aGUgY2h1bmsgb3IgYnkgcGxhY2luZyB5b3VyIGN1cnNvciBpbnNpZGUgaXQgYW5kIHByZXNzaW5nICpDdHJsK1NoaWZ0K0VudGVyKi4gDQoNCkFkZCBhIG5ldyBjaHVuayBieSBjbGlja2luZyB0aGUgKkluc2VydCBDaHVuayogYnV0dG9uIG9uIHRoZSB0b29sYmFyIG9yIGJ5IHByZXNzaW5nICpDdHJsK0FsdCtJKi4NCg0KV2hlbiB5b3Ugc2F2ZSB0aGUgbm90ZWJvb2ssIGFuIEhUTUwgZmlsZSBjb250YWluaW5nIHRoZSBjb2RlIGFuZCBvdXRwdXQgd2lsbCBiZSBzYXZlZCBhbG9uZ3NpZGUgaXQgKGNsaWNrIHRoZSAqUHJldmlldyogYnV0dG9uIG9yIHByZXNzICpDdHJsK1NoaWZ0K0sqIHRvIHByZXZpZXcgdGhlIEhUTUwgZmlsZSkuDQoNClRoZSBwcmV2aWV3IHNob3dzIHlvdSBhIHJlbmRlcmVkIEhUTUwgY29weSBvZiB0aGUgY29udGVudHMgb2YgdGhlIGVkaXRvci4gQ29uc2VxdWVudGx5LCB1bmxpa2UgKktuaXQqLCAqUHJldmlldyogZG9lcyBub3QgcnVuIGFueSBSIGNvZGUgY2h1bmtzLiBJbnN0ZWFkLCB0aGUgb3V0cHV0IG9mIHRoZSBjaHVuayB3aGVuIGl0IHdhcyBsYXN0IHJ1biBpbiB0aGUgZWRpdG9yIGlzIGRpc3BsYXllZC4NCg0KYGBge3J9DQpzZXR3ZCgiRDovUiBwcm9ncmFtIikNCiN2YWx1ZXMgbmVlZGVkIA0KDQpLPSAxLjM4MDY0ODUyKigxMCleLTIzICNtMiBrZy8gczIgSyBib2x0em1hbm4gY29uc3RhbnQNCm11PSAxLjEyNiooMTApXi0zICNrZy9tIHMgZHluYW1pYyB2aXNjb3NpdHkgaW4gMThDDQp2PSAxLjA5OSooMTApXi02ICNtMi9zIGtpbmVtYXRpYyB2aXNjb3NpdHkgaW4gMThDDQpSZWhfY2FsYz0gMi4zRS02ICNpbiBtIHJhZGl1cyBFaHV4DQpSZWhfbmFrZWQ9IDEuOEUtNiAjaW4gbSByYWRpdXMgRWh1eA0KUmVodj0gOTAqKDEwKV4tOSAjaW4gbSByYWRpdXMgdmlydXMNClRlbXAgPSAxOCsyNzMuMTUgI3RlbXAgaW4ga2VsdmluLCBoZXJlIGFzc3VtaW5nIDE4Qw0KRGVuX09jTSA9IDEuMDUgI2cvY20zIGRlbnNpdHkgb3JnYW5pYyBjZWxsIG1hdHRlcg0KRGVuX0NIMk89IDEuMDI1ICNnL2NtMyBkZW5zaXR5IHNlYXdhdGVyIGF0IDE4Qw0KaG9zdG51bSA8LSAoMTApXjMNCnZpcm51bSA8LSAoMTApXjQNCg0KcmVxdWlyZSAoZ2dwbG90MikNCnJlcXVpcmUocGxvdGx5KQ0KcmVxdWlyZShncmlkKQ0KcmVxdWlyZShnZ3RoZW1lcykNCnJlcXVpcmUgKGRwbHlyKQ0KcmVxdWlyZShwbHlyKQ0Kc291cmNlICgidGhlbWVfUHVibGljYXRpb24uUiIpDQpzb3VyY2UoInJlc2l6ZXdpbi5SIikNCnJlc2l6ZS53aW4oMTIsOSkNCmdyaWQubmV3cGFnZSgpDQoNCmBgYA0KDQpmb3IgQnJvd25pYW4gbW90aW9uDQoNCmBgYHtyfQ0KI0Jyb3duaWFuIG1vdGlvbiAoQk0pDQojMS4gbWFrZSBhIGRhdGEgZnJhbWUNCkJNIDwtIGRhdGEuZnJhbWUgKGdyb3VwPSBjKCJuYWtlZCIsICJjYWxjaWZpZWQiKSwgcmFkPSBjKDEuOEUtNiwgMi4zRS02KSkgDQoNCiMyLiBjYWxjdWxhdGUgYmV0YSAoYmV0YSkNCkJNJGJldGFfcyA8LSAoMiooSyooMTApXjQpKlRlbXAqKCgoQk0kcmFkK1JlaHYpKjEwMCleMikpLygoMyptdSoxMCkqKEJNJHJhZCpSZWh2KjFlNCkpICNtMy9zDQpCTSRiZXRhX2QgPC0gQk0kYmV0YV9zKjg2NDAwICN0byBjbTMvZGF5DQoNCiMgZ28gYmFjayB0byB0aGlzIGxhdGVyDQojMy4gY2FsY3VsYXRlIGVuY291bnRlcnMgKEUpDQpCTSRFIDwtIEJNJGJldGFfZCpob3N0bnVtDQpCTSRFX0hWIDwtIEJNJGJldGFfZCp2aXJudW0qaG9zdG51bQ0KDQpCTQ0KYGBgDQoNCkRpZmZlcmVudGlhbCBzZXR0bGluZyAoRFMpDQoNCmBgYHtyfQ0KI0RpZmZlcmVudGlhbCBzZXR0bGluZyAoRFMpDQojMS4gcmVhZCBpbiBQSUMgZGF0YQ0KbGlicmFyeShyZWFkcikgI2Fsd2F5cyB1c2UgcmVhZHIgbm90IGJhc2VSDQoNCnNldHdkKCJEOi9SIHByb2dyYW0iKQ0KUElDIDwtIHJlYWRfY3N2KCJQb3N0ZG9jLVIvQ1NWIEZpbGVzL1BJQy5jc3YiKQ0KDQpQSUMkU3RyYWluIDwtIGFzLmZhY3RvcihQSUMkU3RyYWluKQ0KUElDJFJlcGxpY2F0ZSA8LSBhcy5mYWN0b3IoUElDJFJlcGxpY2F0ZSkNCg0KI2NlcnRhaW4gY2hhbmdlcyBpbiBkYXRhLnRhYmxlIEFQSSBtYWRlIGNhbGN1bGF0aW5nIGluc2lkZSB0aGUgbGlzdCBkYXRhLnRhYmxlIHRvIG5vdCB3b3JrDQoNCiMyLiBjYWxjdWxhdGUgUElDDQpQSUMkUElDIDwtIFBJQyRUQy1QSUMkQUMNClBJQyRQSUNwZXJjZWxsIDwtIChQSUMkUElDL1BJQyRDZWxsY291bnQpKigxMCleLTMjaW4gZw0KUElDJFBJQ3BlcmNlbGxwZyA8LSBQSUMkUElDcGVyY2VsbCoxZTEyDQoNCmdncGxvdGx5KGdncGxvdChkYXRhPVBJQywgYWVzKHg9U3RyYWluLCB5PVBJQ3BlcmNlbGxwZykpICsgZ2VvbV9ib3hwbG90KCkrZ2VvbV9wb2ludChzaXplPTIpICt0aGVtZV9QdWJsaWNhdGlvbigpKQ0KDQpgYGANCg0KYGBge3J9DQoNCiMzLiBjYWxjdWxhdGUgZGVuc2l0eSBvZiBjZWxscyAoZGVuKQ0KUElDIDwtIG11dGF0ZShQSUMsIGdyb3VwID0gaWZlbHNlKFBJQ3BlcmNlbGxwZyA8IDQgLCAibmFrZWQiLCAiY2FsY2lmaWVkIikpDQoNCmdncGxvdGx5KGdncGxvdChkYXRhPVBJQywgYWVzKHg9Z3JvdXAsIHk9UElDcGVyY2VsbHBnKSkgKyBnZW9tX2JveHBsb3QoKStnZW9tX3BvaW50KHNpemU9MiwgYWVzKGNvbG9yPVN0cmFpbikpKw0KICAgICAgICAgICB0aGVtZV9QdWJsaWNhdGlvbigpKQ0KDQpQSUMgPC0gbXV0YXRlKFBJQywgcmFkID0gaWZlbHNlKGdyb3VwID09ICJuYWtlZCIgLCAgMS44RS02LCAgMi4zRS02KSkgI2luIG0NCg0KUElDJHZvbHVtZSA8LSAoNC8zKSpwaSooUElDJHJhZCoxMDApXjMgI2luIGNtMw0KUElDJERlbl9jZWxsIDwtIFBJQyRQSUNwZXJjZWxsL1BJQyR2b2x1bWUgI2cvY20zDQpQSUMkRGVuX2NlbGx0b3RhbCA8LSBQSUMkRGVuX2NlbGwrRGVuX09jTQ0KDQpnZ3Bsb3RseShnZ3Bsb3QoZGF0YT1QSUMsIGFlcyh4PVN0cmFpbiwgeT1EZW5fY2VsbHRvdGFsLCBjb2xvcj1ncm91cCkpICsgZ2VvbV9ib3hwbG90KCkrZ2VvbV9wb2ludChzaXplPTIpIA0KICAgICAgICAgK3RoZW1lX1B1YmxpY2F0aW9uKCkpDQoNCiNzb21lIHN0cmFpbnMgdGhhdCBhcmUgIm5ha2VkIiBoYXZlIFBJQzwyLiBJIGNob3NlIHRvIGlnbm9yZSB0aGlzIHNpbmNlIGluIHRoZSBsbSBtb2RlbCBJIGRvIG5vdCB1c2UNCiNzdHJhaW4gYXMgYSBmYWN0b3IsIHJhdGhlciBkYXRhIGlzIHRyZWF0ZWQgYXMgYSB3aG9sZSAoZS5nLiwgbm8gZ3JvdXBpbmcpDQoNCiM0LiBjYWxjdWxhdGUgc2lua2luZyB2ZWxvY2l0eSBvZiBjZWxscw0KUElDJFNpbmtWZWwgPC0gKCgyKigoUElDJHJhZCoxMDApXjIpKig5ODEpKihQSUMkRGVuX2NlbGx0b3RhbC1EZW5fQ0gyTykpLyg5KihtdSoxMCkpKSo4NjQgI21ldGVyIHBlciBkYXkNCg0KI2cgaXMgY29udmVydGVkIHRvIHBlciBkYXksIDg2NCBpcyB0aGUgb25lIHRoYXQgY29udmVydHMgY20vcyB0byBtL2RheQ0KDQojcGxvdCBzaW5raW5nIHZlbG9jaXR5IHZzIGNhbGNpZmljYXRpb24NCg0KZ2dwbG90KGRhdGE9UElDLCBhZXMoeD1QSUNwZXJjZWxscGcsIHk9U2lua1ZlbCwgY29sb3I9U3RyYWluLCBzaGFwZT1ncm91cCkpICsgZ2VvbV9wb2ludChzaXplPTUpK3RoZW1lX1B1YmxpY2F0aW9uKCkrDQogICAgbGFicyh5ID0gZXhwcmVzc2lvbigiU2lua2luZyB2ZWxvY2l0eSJ+KCJtIn5kYXleLTEpKSwgeCA9IGV4cHJlc3Npb24oIlBJQyJ+Y2VsbF4tMSkpICsNCiAgICBzY2FsZV95X2xvZzEwKA0KICAgICAgICBicmVha3MgPSBzY2FsZXM6OnRyYW5zX2JyZWFrcygibG9nMTAiLCBmdW5jdGlvbih4KSAxMF54LCBuPTIpLA0KICAgICAgICBsYWJlbHMgPSBzY2FsZXM6OnRyYW5zX2Zvcm1hdCgibG9nMTAiLCBzY2FsZXM6Om1hdGhfZm9ybWF0KDEwXi54KSkpICsgYW5ub3RhdGlvbl9sb2d0aWNrcyhzaWRlcz0ibCIpDQoNCiM1LiBjYWxjdWxhdGUgc2lua3ZlbCBvZiB2aXJ1c2VzDQoNCkRlbl92aXJ1cyA8LSAxLjA5ICNkYXRhIGZyb20gQmVuIEQuIGZyZXNoIEVoVi0yMDcgZGVuc2l0eS4gb2xkIGRlbnNpdHkgb2YgRWhWLTIwNyBpcyAxLjE5DQpFaHZfU2lua1ZlbCA8LSAoKDIqKChSZWh2KjEwMCleMikqKDk4MSkqKERlbl92aXJ1cy1EZW5fQ0gyTykpLyg5KihtdSoxMCkpKSo4NjQgICNlcXVhbHMgdG8gMA0KDQojNi4gY2FsY3VsYXRlIGJldGEga2VybmVscw0KUElDJGJldGFfcyA8LSBwaSooKChQSUMkcmFkK1JlaHYpKjEwMCleMikqKGFicygoUElDJFNpbmtWZWwtRWh2X1NpbmtWZWwpLzg2NCkpICNpbiBlbmNvdW50ZXJzIGNtMy9zDQpQSUMkYmV0YV9kIDwtIFBJQyRiZXRhX3MqODY0MDAgI2luIGNtMy9kYXkNCg0KU2lua3ZlbGJldGEucGxvdDwtIGdncGxvdChkYXRhPVBJQywgYWVzKHg9U2lua1ZlbCwgeT1iZXRhX2QsIGNvbG9yPVN0cmFpbiwgc2hhcGU9Z3JvdXApKSArIGdlb21fcG9pbnQoc2l6ZT01KSsNCiAgdGhlbWVfUHVibGljYXRpb24oKSsNCiAgbGFicyh4ID0gZXhwcmVzc2lvbigiU2lua2luZyB2ZWxvY2l0eSJ+KCJtIn5kYXleLTEpKSwgeSA9IGV4cHJlc3Npb24oYmV0YX4oIkVuY291bnRlcnMiIH4gY21eM35kYXleLTEpKSkgKw0KIHNjYWxlX3lfbG9nMTAoDQogICAgICAgIGJyZWFrcyA9IHNjYWxlczo6dHJhbnNfYnJlYWtzKCJsb2cxMCIsIGZ1bmN0aW9uKHgpIDEwXngsIG49MiksDQogICAgICAgIGxhYmVscyA9IHNjYWxlczo6dHJhbnNfZm9ybWF0KCJsb2cxMCIsIHNjYWxlczo6bWF0aF9mb3JtYXQoMTBeLngpKSkgKyBhbm5vdGF0aW9uX2xvZ3RpY2tzKHNpZGVzPSJsIikNCg0KU2lua3ZlbGJldGEucGxvdCAjY2hhbmdlIHRpY2tzDQoNCmdncGxvdGx5KFNpbmt2ZWxiZXRhLnBsb3QpDQoNCmdncGxvdGx5KGdncGxvdChkYXRhPVBJQywgYWVzKHg9U3RyYWluLCB5PVNpbmtWZWwpKSArIGdlb21fYm94cGxvdCgpK3RoZW1lX1B1YmxpY2F0aW9uKCkpDQoNCmdncGxvdChkYXRhPVBJQywgYWVzKHg9UElDcGVyY2VsbHBnLCB5PWJldGFfZCwgY29sb3I9U3RyYWluKSkgKyBnZW9tX3BvaW50KHNpemU9NSkrdGhlbWVfUHVibGljYXRpb24oKSsNCiAgbGFicyh5ID0gZXhwcmVzc2lvbihiZXRhfigiRW5jb3VudGVycyJ+Y21eM35kYXleLTEpKSwgeCA9IGV4cHJlc3Npb24oIlBJQyJ+Y2VsbF4tMSkpICArDQpzY2FsZV95X2xvZzEwKA0KICAgICAgICBicmVha3MgPSBzY2FsZXM6OnRyYW5zX2JyZWFrcygibG9nMTAiLCBmdW5jdGlvbih4KSAxMF54LCBuPTIpLA0KICAgICAgICBsYWJlbHMgPSBzY2FsZXM6OnRyYW5zX2Zvcm1hdCgibG9nMTAiLCBzY2FsZXM6Om1hdGhfZm9ybWF0KDEwXi54KSkpICsgYW5ub3RhdGlvbl9sb2d0aWNrcyhzaWRlcz0ibCIpDQoNCmBgYA0KDQpgYGB7cn0NCiM3LiBjYWxjdWxhdGUgYmV0YSBhbmQgZW5jb3VudGVycw0KI2JldGEgYXJlIGluIGNlbGxzIGNtMy8gZGF5IHRoZW4gZW5jb3VudGVycyBhcmUgdG8gY2VsbHMvY20zIGRheQ0KUElDJEVfRFNfSFYgPC0gKFBJQyRiZXRhX2QqdmlybnVtKmhvc3RudW0pICAjRSBjYWxjdWxhdGVkIHdpdGggVmlydXMgYW5kIEhvc3QgKDEwOjEgTU9JKQ0KUElDJEVfRFNfViA8LSAoUElDJGJldGFfZCp2aXJudW0pICNFIGNhbGN1bGF0ZWQgd2l0aCBWaXJ1cw0KDQojOC4gY2FsY3VsYXRlIGZvciBsaXRoIHBhcmFtZXRlcnMNCg0KbGl0aHZvbCA8LSAzKjFlLTEyICNpbiBjbTMsIGZyb20gQ0oncyBwYXBlcg0KUElDJHBlcmxpdGggPC0gUElDJFBJQ3BlcmNlbGwvMjAgI2luIGcsIGFzc3VtaW5nIDIwIGxpdGhzIGF0dGFjaGVkDQpQSUMkcGVybGl0aHBnIDwtIFBJQyRwZXJsaXRoKjFlMTIgI2luIHBnDQpQSUMkRGVubGl0aCA8LSAoUElDJHBlcmxpdGgvbGl0aHZvbCkgKyBEZW5fT2NNICNpbiBnL2NtMywgd2l0aCBvcmdhbmljIG1hdHRlciBhdHRhY2hlZA0KcmFkX2xpdGggPC0gMkUtNiAjaW4gbSByYWRpdXMNCg0KUElDJFNpbmtWZWxfbGl0aCA8LSAoKDIqKChyYWRfbGl0aCoxMDApXjIpKig5ODEpKihQSUMkRGVubGl0aC1EZW5fQ0gyTykpLyg5KihtdSoxMCkpKSo4NjQgI21ldGVyIHBlciBkYXkNClBJQyRiZXRhX3NfbGl0aCA8LSBwaSooKChyYWRfbGl0aCtSZWh2KSoxMDApXjIpKihhYnMoKFBJQyRTaW5rVmVsX2xpdGgtRWh2X1NpbmtWZWwpLzg2NCkpICNpbiBlbmNvdW50ZXJzIGNtMy9zDQpQSUMkYmV0YV9kX2xpdGggPC0gUElDJGJldGFfc19saXRoKjg2NDAwICNpbiBjbTMvZGF5DQoNCmdncGxvdChkYXRhPVBJQywgYWVzKHg9cGVybGl0aHBnLCB5PVNpbmtWZWxfbGl0aCwgY29sb3I9U3RyYWluLCBzaGFwZT1ncm91cCkpICsgZ2VvbV9wb2ludChzaXplPTUpK3RoZW1lX1B1YmxpY2F0aW9uKCkrDQogIGxhYnMoeSA9IGV4cHJlc3Npb24oIlNpbmtpbmcgdmVsb2NpdHkifigibSJ+ZGF5Xi0xKSksIHggPSBleHByZXNzaW9uKCJQSUMifmxpdGheLTEpKSANCg0KUElDJEVsaXRoX0RTX0hWIDwtIChQSUMkYmV0YV9kX2xpdGgqdmlybnVtKmhvc3RudW0pICAjRSBjYWxjdWxhdGVkIHdpdGggVmlydXMgYW5kIEhvc3QgKDEwOjEgTU9JKQ0KUElDJEVsaXRoX0RTX1YgPC0gKFBJQyRiZXRhX2RfbGl0aCp2aXJudW0pICNFIGNhbGN1bGF0ZWQgd2l0aCBWaXJ1cw0KDQpyZXF1aXJlIChkcGx5cikNCg0KUElDJGdyb3VwMiA8LSBjYXNlX3doZW4oDQogIFBJQyRQSUNwZXJjZWxscGcgPDIgIH4gIm5ha2VkX2JvdXlhbnQiLA0KICBQSUMkUElDcGVyY2VsbHBnID4yICYgUElDJFBJQ3BlcmNlbGxwZyA8IDQgfiAibmFrZWQvY2FsY2lmaWVkIHVuY2VydGFpbiIsDQogIFBJQyRQSUNwZXJjZWxscGcgPjQgJiBQSUMkUElDcGVyY2VsbHBnIDwgMTAgfiAibW9kZXJhdGVseSBjYWxjaWZpZWQiLA0KICBQSUMkUElDcGVyY2VsbHBnID4xMCB+ICJzdHJvbmdseSBjYWxjaWZpZWQiLCANCiAgVFJVRSB+IGFzLmNoYXJhY3RlcihQSUMkUElDcGVyY2VsbHBnKQ0KKQ0KDQpicmVha3MgPC0gMTBeKC0xMDoxMCkNCg0KZ2dwbG90KGRhdGE9UElDLCBhZXMoeD1TaW5rVmVsLCB5PUVfRFNfSFYsIGNvbG9yPVN0cmFpbiwgc2hhcGU9Z3JvdXApKSArIGdlb21fcG9pbnQoc2l6ZT01KSt0aGVtZV9QdWJsaWNhdGlvbigpKw0KIHNjYWxlX3lfbG9nMTAoDQogICAgICAgIGJyZWFrcyA9IHNjYWxlczo6dHJhbnNfYnJlYWtzKCJsb2cxMCIsIGZ1bmN0aW9uKHgpIDEwXngsIG49MiksDQogICAgICAgIGxhYmVscyA9IHNjYWxlczo6dHJhbnNfZm9ybWF0KCJsb2cxMCIsIHNjYWxlczo6bWF0aF9mb3JtYXQoMTBeLngpKSkgKyBhbm5vdGF0aW9uX2xvZ3RpY2tzKHNpZGVzPSJsIikNCg0KDQpnZ3Bsb3QoZGF0YT1QSUMsIGFlcyh4PVNpbmtWZWwsIHk9RV9EU19WLCBjb2xvcj1TdHJhaW4sIHNoYXBlPWdyb3VwKSkgKyBnZW9tX3BvaW50KHNpemU9NSkrdGhlbWVfUHVibGljYXRpb24oKSsNCiAgc2NhbGVfeV9sb2cxMCgNCiAgICAgICAgYnJlYWtzID0gc2NhbGVzOjp0cmFuc19icmVha3MoImxvZzEwIiwgZnVuY3Rpb24oeCkgMTBeeCwgbj0yKSwNCiAgICAgICAgbGFiZWxzID0gc2NhbGVzOjp0cmFuc19mb3JtYXQoImxvZzEwIiwgc2NhbGVzOjptYXRoX2Zvcm1hdCgxMF4ueCkpKSArIGFubm90YXRpb25fbG9ndGlja3Moc2lkZXM9ImwiKQ0KDQoNCmdncGxvdChkYXRhPVBJQywgYWVzKHg9U2lua1ZlbF9saXRoLCB5PUVsaXRoX0RTX1YsIGNvbG9yPVN0cmFpbiwgc2hhcGU9Z3JvdXApKSArIGdlb21fcG9pbnQoc2l6ZT01KSArIA0KICB0aGVtZV9QdWJsaWNhdGlvbigpICsgc2NhbGVfeV9sb2cxMCgNCiAgICAgICAgYnJlYWtzID0gc2NhbGVzOjp0cmFuc19icmVha3MoImxvZzEwIiwgZnVuY3Rpb24oeCkgMTBeeCwgbj0zKSwNCiAgICAgICAgbGFiZWxzID0gc2NhbGVzOjp0cmFuc19mb3JtYXQoImxvZzEwIiwgc2NhbGVzOjptYXRoX2Zvcm1hdCgxMF4ueCkpKSArIGFubm90YXRpb25fbG9ndGlja3Moc2lkZXM9ImwiKQ0KDQoNCg0Kc3VtbWFyeV9EUyA8LSBkZHBseShQSUMsIC4oU3RyYWluKSwgc3VtbWFyaXplLCAgUElDcGVyY2VsbHBnPW1lYW4oUElDcGVyY2VsbHBnKSwgcGVybGl0aHBnID0gbWVhbihwZXJsaXRocGcpLCANCiAgICAgICAgICAgICAgICAgICAgRGVuX2NlbGx0b3RhbCA9IG1lYW4gKERlbl9jZWxsdG90YWwpLA0KICAgICAgICAgICAgICAgICAgICBTaW5rVmVsPW1lYW4oU2lua1ZlbCksYmV0YV9kPW1lYW4oYmV0YV9kKSwgRV9EU19WPSBtZWFuKEVfRFNfViksIEVfRFNfSFY9bWVhbihFX0RTX0hWKSwNCiAgICAgICAgICAgICAgICAgICAgU2lua1ZlbF9saXRoPW1lYW4gKFNpbmtWZWxfbGl0aCksIGJldGFfZF9saXRoPW1lYW4gKGJldGFfZF9saXRoKSwgRWxpdGhfRFNfSFY9bWVhbiAoRWxpdGhfRFNfSFYpLA0KICAgICAgICAgICAgICAgICAgICBFbGl0aF9EU19WPW1lYW4gKEVsaXRoX0RTX1YpKQ0KDQpzdW1tYXJ5X0RTX2J5Z3JvdXAgPC0gZGRwbHkoUElDLCAuKGdyb3VwMiksIHN1bW1hcml6ZSwgIFBJQ3BlcmNlbGxwZz1tZWFuKFBJQ3BlcmNlbGxwZyksIHBlcmxpdGhwZyA9IG1lYW4ocGVybGl0aHBnKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgRGVuX2NlbGx0b3RhbCA9IG1lYW4gKERlbl9jZWxsdG90YWwpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNpbmtWZWw9bWVhbihTaW5rVmVsKSxiZXRhX2Q9bWVhbihiZXRhX2QpLCBFX0RTX1Y9IG1lYW4oRV9EU19WKSwgRV9EU19IVj1tZWFuKEVfRFNfSFYpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBTaW5rVmVsX2xpdGg9bWVhbiAoU2lua1ZlbF9saXRoKSwgYmV0YV9kX2xpdGg9bWVhbiAoYmV0YV9kX2xpdGgpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBFbGl0aF9EU19IVj1tZWFuIChFbGl0aF9EU19IViksIEVsaXRoX0RTX1Y9bWVhbiAoRWxpdGhfRFNfVikpDQoNCnN1bW1hcnlfRFMNCnN1bW1hcnlfRFNfYnlncm91cA0KDQpzZXR3ZCgiRDovUiBwcm9ncmFtIikNCnJlcXVpcmUob3Blbnhsc3gpDQp3cml0ZS54bHN4KHN1bW1hcnlfRFMsIGZpbGUgPSAiUG9zdGRvYy1SL0V4cG9ydGVkIFRhYmxlcy9zdW1tYXJ5X0RTLnhsc3giKQ0Kd3JpdGUueGxzeChzdW1tYXJ5X0RTX2J5Z3JvdXAsIGZpbGUgPSAiUG9zdGRvYy1SL0V4cG9ydGVkIFRhYmxlcy9zdW1tYXJ5X0RTX2J5Z3JvdXAueGxzeCIpDQoNCmBgYA0KDQpgYGB7cn0NCg0KIzkuIHJlZ3Jlc3Npb24gb2YgUElDIGFuZCBzaW5rdmVsIG9mIGNlbGxzIGFuZCBsaXRocw0KDQojYS4gZm9yIGNlbGxzDQpQSUNfcmVnIDwtIGxtKFNpbmtWZWx+UElDcGVyY2VsbHBnLCBkYXRhPVBJQykgI2Vzc2VudGlhbGx5IHBlcmZlY3QgZml0OiBzdW1tYXJ5IG1heSBiZSB1bnJlbGlhYmxlIGhhaGENCnN1bW1hcnkoUElDX3JlZykNCnBsb3QocmVzaWR1YWxzLmxtKFBJQ19yZWcpKQ0KbGF5b3V0KG1hdHJpeCgxOjQsMiwyKSkNCnBsb3QoUElDX3JlZykNCg0KY29lZihQSUNfcmVnKQ0KIyBjb2VmKFBJQ19yZWcpDQojKEludGVyY2VwdCkgUElDcGVyY2VsbHBnIA0KIzAuMDE4MDA4NTIgICAwLjAxNzc0NzY0IA0KDQpjb3IoUElDJFBJQ3BlcmNlbGxwZywgUElDJFNpbmtWZWwpDQojY29yID0gMC45OTg5MDQyDQoNCmJldGFfcmVnIDwtIGxtKGJldGFfZH5QSUNwZXJjZWxscGcsIGRhdGE9UElDKQ0KcGxvdChyZXNpZHVhbHMubG0oYmV0YV9yZWcpKQ0KY29lZihiZXRhX3JlZykNCiNjb2VmKGJldGFfcmVnKQ0KIyAoSW50ZXJjZXB0KSBQSUNwZXJjZWxscGcgDQojMS42MzkyMzNlLTA3IDMuMjQzMDU0ZS0wNw0KDQpFX0RTX0hWX3JlZyA8LSBsbShFX0RTX0hWflBJQ3BlcmNlbGxwZywgZGF0YT1QSUMpDQpFX0RTX1ZfcmVnIDwtIGxtKEVfRFNfVn5QSUNwZXJjZWxscGcsIGRhdGE9UElDKQ0KcGxvdChyZXNpZHVhbHMubG0oRV9EU19IVl9yZWcpKQ0KcGxvdChyZXNpZHVhbHMubG0oRV9EU19WX3JlZykpDQpjb2VmKEVfRFNfSFZfcmVnKQ0KY29lZihFX0RTX1ZfcmVnKQ0KDQojYi4gZm9yIGxpdGhzDQpwZXJsaXRoX3JlZyA8LSBsbSAocGVybGl0aHBnflBJQ3BlcmNlbGxwZywgZGF0YT1QSUMpDQpwbG90KHJlc2lkKHBlcmxpdGhfcmVnKSkNCmNvZWYocGVybGl0aF9yZWcpDQpzaW5rdmVsX2xpdGhfcmVnIDwtIGxtKFNpbmtWZWxfbGl0aH5QSUNwZXJjZWxscGcsIGRhdGEgPSBQSUMpDQpzdW1tYXJ5KHNpbmt2ZWxfbGl0aF9yZWcpDQpwbG90KHJlc2lkdWFscy5sbShzaW5rdmVsX2xpdGhfcmVnKSkNCmxheW91dChtYXRyaXgoMTo0LDIsMikpDQpwbG90KHNpbmt2ZWxfbGl0aF9yZWcpDQpjb2VmKHNpbmt2ZWxfbGl0aF9yZWcpDQoNCmJldGFfbGl0aF9yZWcgPC0gbG0oYmV0YV9kX2xpdGh+UElDcGVyY2VsbHBnLCBkYXRhPVBJQykNCnBsb3QocmVzaWR1YWxzLmxtKGJldGFfbGl0aF9yZWcpKQ0KY29lZihiZXRhX2xpdGhfcmVnKQ0KDQpFbGl0aF9EU19IVl9yZWcgPC0gbG0oRWxpdGhfRFNfSFZ+UElDcGVyY2VsbHBnLCBkYXRhPVBJQykNCkVsaXRoX0RTX1ZfcmVnIDwtIGxtKEVsaXRoX0RTX1Z+UElDcGVyY2VsbHBnLCBkYXRhPVBJQykNCnBsb3QocmVzaWR1YWxzLmxtKEVsaXRoX0RTX0hWX3JlZykpDQpwbG90KHJlc2lkdWFscy5sbShFbGl0aF9EU19WX3JlZykpDQpjb2VmKEVsaXRoX0RTX0hWX3JlZykNCmNvZWYoRWxpdGhfRFNfVl9yZWcpDQoNCmBgYA0KDQpgYGB7cn0NCg0KIyA5LiBtYWtlIG5ldyBkYXRhZnJhbWUgZGVwZW5kaW5nIG9uIGV4cGVyaW1lbnRhbCBQSUMgdmFsdWVzDQojIG1ha2UgYSBwcmVkaWN0aW9uIGJhc2VkIG9uIFBJQyB2YWx1ZXMNCnJlcXVpcmUodHJ1bmNub3JtKQ0KcmVxdWlyZShSbWlzYykNCnN1bW1hcnkoUElDJFBJQ3BlcmNlbGxwZykNCnN1bW1hcnlTRShkYXRhPVBJQywgbWVhc3VyZXZhcj0iUElDcGVyY2VsbHBnIikNClBJQ19uZXdkYXRhIDwtIGFzLmRhdGEuZnJhbWUocnRydW5jbm9ybShuPTEwMDAsIGE9LTEuNiwgYj0yMC4xNCwgbWVhbj00LjcsIHNkPTYuMTUpKQ0KDQojcmVuYW1lIGNvbHVtbi4gcmVuYW1lIGZ1bmN0aW9uIGluIHBseXIgDQpsaWJyYXJ5KHBseXIpDQpQSUNfbmV3ZGF0YSA8LSByZW5hbWUgKFBJQ19uZXdkYXRhLCBjICgicnRydW5jbm9ybShuID0gMTAwMCwgYSA9IC0xLjYsIGIgPSAyMC4xNCwgbWVhbiA9IDQuNywgc2QgPSA2LjE1KSIgPSANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlBJQ3BlcmNlbGxwZyIpKQ0KDQpQSUNfbmV3ZGF0YSA8LSBtdXRhdGUoUElDX25ld2RhdGEsIGdyb3VwID0gaWZlbHNlKFBJQ3BlcmNlbGxwZyA8IDQgLCAibmFrZWQiLCAiY2FsY2lmaWVkIikpDQoNCmdncGxvdGx5KGdncGxvdChkYXRhPVBJQ19uZXdkYXRhLCBhZXMoeD1ncm91cCwgeT1QSUNwZXJjZWxscGcpKSArIGdlb21fYm94cGxvdCgpK2dlb21fcG9pbnQoc2l6ZT0yKSArDQogICAgICAgICAgIHRoZW1lX1B1YmxpY2F0aW9uKCkpDQoNClBJQ19uZXdkYXRhJGdyb3VwMiA8LSBjYXNlX3doZW4oDQogIFBJQ19uZXdkYXRhJFBJQ3BlcmNlbGxwZyA8MiAgfiAibmFrZWRfYm91eWFudCIsDQogIFBJQ19uZXdkYXRhJFBJQ3BlcmNlbGxwZyA+MiAmIFBJQ19uZXdkYXRhJFBJQ3BlcmNlbGxwZyA8IDQgfiAibmFrZWQvY2FsY2lmaWVkIHVuY2VydGFpbiIsDQogIFBJQ19uZXdkYXRhJFBJQ3BlcmNlbGxwZyA+NCAmIFBJQ19uZXdkYXRhJFBJQ3BlcmNlbGxwZyA8IDEwIH4gIm1vZGVyYXRlbHkgY2FsY2lmaWVkIiwNCiAgUElDX25ld2RhdGEkUElDcGVyY2VsbHBnID4xMCB+ICJzdHJvbmdseSBjYWxjaWZpZWQiLCANCiAgVFJVRSB+IGFzLmNoYXJhY3RlcihQSUNfbmV3ZGF0YSRQSUNwZXJjZWxscGcpDQopDQoNCmdncGxvdGx5KGdncGxvdChkYXRhPVBJQ19uZXdkYXRhLCBhZXMoeD1ncm91cDIsIHk9UElDcGVyY2VsbHBnKSkgKyANCiAgICAgICAgICAgZ2VvbV9ib3hwbG90KCkrZ2VvbV9wb2ludChzaXplPTIpICt0aGVtZV9QdWJsaWNhdGlvbigpKQ0KDQojYS4gZm9yIGhvc3QNClBJQ19uZXdkYXRhJFNpbmtWZWwucHJlZCA8LSBwcmVkaWN0KFBJQ19yZWcsIGRhdGEuZnJhbWUoUElDX25ld2RhdGEpKQ0KUElDX25ld2RhdGFfcmVnIDwtIGxtKFNpbmtWZWwucHJlZH5QSUNwZXJjZWxscGcsIGRhdGE9UElDX25ld2RhdGEpIA0KY29lZihQSUNfbmV3ZGF0YV9yZWcpDQojc2FtZSBjb2VmIGFzIFBJQ19yZWcNCiM+IGNvZWYoUElDX25ld2RhdGFfcmVnKQ0KIyhJbnRlcmNlcHQpIFBJQ3BlcmNlbGxwZyANCiMwLjAxODAwODUyICAgMC4wMTc3NDc2NCANCg0KcGxvdChyZXNpZChQSUNfbmV3ZGF0YV9yZWcpKQ0KDQpnZ3Bsb3QoZGF0YT1QSUNfbmV3ZGF0YSwgYWVzKHg9UElDcGVyY2VsbHBnLCB5PVNpbmtWZWwucHJlZCkpICtnZW9tX3BvaW50KHNpemU9MikgK3RoZW1lX1B1YmxpY2F0aW9uKCkrDQogIGxhYnMoeSA9IGV4cHJlc3Npb24oIlByZWRpY3RlZCBTaW5raW5nIHZlbG9jaXR5In4oIm0ifmRheV4tMSkpLCB4ID0gZXhwcmVzc2lvbigiUElDIn5jZWxsXi0xKSkgDQoNClBJQ19uZXdkYXRhJGJldGEucHJlZCA8LSBwcmVkaWN0KGJldGFfcmVnLCBkYXRhLmZyYW1lKFBJQ19uZXdkYXRhKSkNClBJQ19uZXdkYXRhJEVfRFNfVi5wcmVkIDwtIHByZWRpY3QoRV9EU19WX3JlZywgZGF0YS5mcmFtZShQSUNfbmV3ZGF0YSkpDQpQSUNfbmV3ZGF0YSRFX0RTX0hWLnByZWQgPC0gcHJlZGljdChFX0RTX0hWX3JlZywgZGF0YS5mcmFtZShQSUNfbmV3ZGF0YSkpDQoNCmdncGxvdChkYXRhPVBJQ19uZXdkYXRhLCBhZXMoeD1QSUNwZXJjZWxscGcsIHk9RV9EU19WLnByZWQpKSArZ2VvbV9wb2ludChzaXplPTUsIGFlcyhjb2xvcj1ncm91cDIpKSArDQogIHRoZW1lX1B1YmxpY2F0aW9uKCkgKyBnZW9tX3Ntb290aCgpICsNCiAgc2NhbGVfeV9sb2cxMCgNCiAgICAgICAgYnJlYWtzID0gc2NhbGVzOjp0cmFuc19icmVha3MoImxvZzEwIiwgZnVuY3Rpb24oeCkgMTBeeCwgbj00KSwNCiAgICAgICAgbGFiZWxzID0gc2NhbGVzOjp0cmFuc19mb3JtYXQoImxvZzEwIiwgc2NhbGVzOjptYXRoX2Zvcm1hdCgxMF4ueCkpKSArIGFubm90YXRpb25fbG9ndGlja3Moc2lkZXM9ImwiKQ0KICANCg0KUElDYmV0YV9uZXcgPC0gZ2dwbG90KGRhdGE9UElDX25ld2RhdGEsIGFlcyh4PVBJQ3BlcmNlbGxwZywgeT1iZXRhLnByZWQpKSArDQogIGdlb21fcG9pbnQoc2l6ZT01LCBhZXMoY29sb3I9UElDcGVyY2VsbHBnKSkrDQogIHNjYWxlX2NvbG91cl9ncmFkaWVudChuYW1lPSJQSUMiLCBndWlkZT1ndWlkZV9jb2xvcmJhcihkaXJlY3Rpb24gPSAidmVydGljYWwiLCBiYXJoZWlnaHQ9MTApKSsNCiAgdGhlbWVfUHVibGljYXRpb24oKSArIA0KICBzY2FsZV95X2xvZzEwKA0KICAgICAgICBicmVha3MgPSBzY2FsZXM6OnRyYW5zX2JyZWFrcygibG9nMTAiLCBmdW5jdGlvbih4KSAxMF54LCBuPTQpLA0KICAgICAgICBsYWJlbHMgPSBzY2FsZXM6OnRyYW5zX2Zvcm1hdCgibG9nMTAiLCBzY2FsZXM6Om1hdGhfZm9ybWF0KDEwXi54KSkpICsgYW5ub3RhdGlvbl9sb2d0aWNrcyhzaWRlcz0ibCIpICsNCiAgbGFicyh5ID0gZXhwcmVzc2lvbihiZXRhfigiUHJlZGljdGVkIEVuY291bnRlcnMifmNtXjN+ZGF5Xi0xKSksIHggPSBleHByZXNzaW9uKCJQSUMifmNlbGxeLTEpKSsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IikNClBJQ2JldGFfbmV3DQoNCiNiLiBmb3IgbGl0aHMNClBJQ19uZXdkYXRhJHBlcmxpdGhwZy5wcmVkIDwtIHByZWRpY3QocGVybGl0aF9yZWcsIGRhdGEuZnJhbWUoUElDX25ld2RhdGEpKQ0KUElDX25ld2RhdGEkU2lua1ZlbC5wcmVkLmxpdGggPC0gcHJlZGljdChzaW5rdmVsX2xpdGhfcmVnLCBkYXRhLmZyYW1lKFBJQ19uZXdkYXRhKSkNCnNpbmt2ZWxfbGl0aF9yZWcucHJlZCA8LSBsbShTaW5rVmVsLnByZWQubGl0aH5QSUNwZXJjZWxscGcsIGRhdGE9UElDX25ld2RhdGEpIA0KY29lZihzaW5rdmVsX2xpdGhfcmVnLnByZWQpDQojc2FtZSBjb2VmIGFzIHNpbmt2ZWxfbGl0aF9yZWcNCiM+IGNvZWYoc2lua3ZlbF9saXRoX3JlZy5wcmVkKQ0KIyhJbnRlcmNlcHQpIFBJQ3BlcmNlbGxwZyANCiMgMC4wMTY3Mjc1MyAgIDAuMDExMTUxNjkgDQoNCnBsb3QocmVzaWQoc2lua3ZlbF9saXRoX3JlZy5wcmVkKSkNCg0KZ2dwbG90KGRhdGE9UElDX25ld2RhdGEsIGFlcyh4PXBlcmxpdGhwZy5wcmVkLCB5PVNpbmtWZWwucHJlZC5saXRoKSkgK2dlb21fcG9pbnQoc2l6ZT0yKSArdGhlbWVfUHVibGljYXRpb24oKSsNCiAgbGFicyh5ID0gZXhwcmVzc2lvbigiUHJlZGljdGVkIFNpbmtpbmcgdmVsb2NpdHkgb2YgTGl0aHMifigibSJ+ZGF5Xi0xKSksIHggPSBleHByZXNzaW9uKCJQSUMifmxpdGheLTEpKSANCg0KUElDX25ld2RhdGEkYmV0YS5wcmVkLmxpdGggPC0gcHJlZGljdChiZXRhX2xpdGhfcmVnLCBkYXRhLmZyYW1lKFBJQ19uZXdkYXRhKSkNClBJQ19uZXdkYXRhJEVfRFNfVi5wcmVkLmxpdGggPC0gcHJlZGljdChFbGl0aF9EU19IVl9yZWcsIGRhdGEuZnJhbWUoUElDX25ld2RhdGEpKQ0KUElDX25ld2RhdGEkRV9EU19IVi5wcmVkLmxpdGggPC0gcHJlZGljdChFbGl0aF9EU19IVl9yZWcsIGRhdGEuZnJhbWUoUElDX25ld2RhdGEpKQ0KDQpnZ3Bsb3QoZGF0YT1QSUNfbmV3ZGF0YSwgYWVzKHg9cGVybGl0aHBnLnByZWQsIHk9RV9EU19WLnByZWQubGl0aCkpICtnZW9tX3BvaW50KHNpemU9NSwgYWVzKGNvbG9yPWdyb3VwMikpICsNCiAgdGhlbWVfUHVibGljYXRpb24oKSArIHNjYWxlX3lfbG9nMTAoDQogICAgICAgIGJyZWFrcyA9IHNjYWxlczo6dHJhbnNfYnJlYWtzKCJsb2cxMCIsIGZ1bmN0aW9uKHgpIDEwXngsIG49NCksDQogICAgICAgIGxhYmVscyA9IHNjYWxlczo6dHJhbnNfZm9ybWF0KCJsb2cxMCIsIHNjYWxlczo6bWF0aF9mb3JtYXQoMTBeLngpKSkgKyBhbm5vdGF0aW9uX2xvZ3RpY2tzKHNpZGVzPSJsIikrIGdlb21fc21vb3RoKCkNCg0KUElDYmV0YV9uZXcubGl0aCA8LSBnZ3Bsb3QoZGF0YT1QSUNfbmV3ZGF0YSwgYWVzKHg9cGVybGl0aHBnLnByZWQsIHk9YmV0YS5wcmVkLmxpdGgpKSArDQogIGdlb21fcG9pbnQoc2l6ZT01LCBhZXMoY29sb3I9UElDcGVyY2VsbHBnKSkrDQogIHNjYWxlX2NvbG91cl9ncmFkaWVudChuYW1lPSJQSUMiLCBndWlkZT1ndWlkZV9jb2xvcmJhcihkaXJlY3Rpb24gPSAidmVydGljYWwiLCBiYXJoZWlnaHQ9MTApKSsNCiAgdGhlbWVfUHVibGljYXRpb24oKSArIA0KICBzY2FsZV95X2xvZzEwKA0KICAgICAgICBicmVha3MgPSBzY2FsZXM6OnRyYW5zX2JyZWFrcygibG9nMTAiLCBmdW5jdGlvbih4KSAxMF54LCBuPTQpLA0KICAgICAgICBsYWJlbHMgPSBzY2FsZXM6OnRyYW5zX2Zvcm1hdCgibG9nMTAiLCBzY2FsZXM6Om1hdGhfZm9ybWF0KDEwXi54KSkpICsgYW5ub3RhdGlvbl9sb2d0aWNrcyhzaWRlcz0ibCIpICsNCiAgbGFicyh5ID0gZXhwcmVzc2lvbihiZXRhfigiUHJlZGljdGVkIEVuY291bnRlcnMgb2YgbGl0aCAiIH5jbV4zfmRheV4tMSkpLCB4ID0gZXhwcmVzc2lvbigiUElDIn5saXRoXi0xKSkrDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpDQpQSUNiZXRhX25ldy5saXRoDQoNCiNzdW1tYXJpZXMNCnN1bW1hcnlfRFNfbmV3ZGF0YV9ieWdyb3VwMiA8LSBkZHBseShQSUNfbmV3ZGF0YSwgLihncm91cDIpLCBzdW1tYXJpemUsICBQSUNwZXJjZWxscGc9bWVhbihQSUNwZXJjZWxscGcpLCBTaW5rVmVsLnByZWQ9bWVhbihTaW5rVmVsLnByZWQpLGJldGEucHJlZD0gbWVhbiAoYmV0YS5wcmVkKSwgRV9EU19WLnByZWQ9IG1lYW4oRV9EU19WLnByZWQpLCBFX0RTX0hWLnByZWQ9bWVhbihFX0RTX0hWLnByZWQpKQ0KDQpzdW1tYXJ5X0RTX2J5Z3JvdXAucHJlZCA8LSBkZHBseShQSUNfbmV3ZGF0YSwgLihncm91cDIpLCBzdW1tYXJpemUsICBQSUNwZXJjZWxscGc9bWVhbihQSUNwZXJjZWxscGcpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwZXJsaXRocGcucHJlZCA9IG1lYW4ocGVybGl0aHBnLnByZWQpLCBTaW5rVmVsLnByZWQ9bWVhbihTaW5rVmVsLnByZWQpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJldGEucHJlZD0gbWVhbiAoYmV0YS5wcmVkKSwgRV9EU19WLnByZWQ9IG1lYW4oRV9EU19WLnByZWQpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBFX0RTX0hWLnByZWQ9bWVhbihFX0RTX0hWLnByZWQpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBTaW5rVmVsLnByZWQubGl0aD1tZWFuKFNpbmtWZWwucHJlZC5saXRoKSxiZXRhLnByZWQubGl0aD0gbWVhbiAoYmV0YS5wcmVkLmxpdGgpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVfRFNfVi5wcmVkLmxpdGg9IG1lYW4oRV9EU19WLnByZWQubGl0aCksIEVfRFNfSFYucHJlZC5saXRoPW1lYW4oRV9EU19IVi5wcmVkLmxpdGgpKQ0KDQpzdW1tYXJ5X0RTX2J5Z3JvdXAucHJlZA0KDQp3cml0ZS54bHN4KHN1bW1hcnlfRFNfYnlncm91cC5wcmVkLCBmaWxlID0gIlBvc3Rkb2MtUi9FeHBvcnRlZCBUYWJsZXMvc3VtbWFyeV9EU19ieWdyb3VwLnByZWQueGxzeCIpDQoNCg0KYGBgDQoNCnR1cmJ1bGVuY2UNCg0KYGBge3J9DQojVFVSQlVMRU5DRQ0KI2Rpc3JhdGUgaXMgY20yL3MzDQoNCiNtYWtlIGRhdGEgZnJhbWUNCg0KZGlzcmF0ZSA8LSByZXBfbGVuKDEwXigtODotMiksIGxlbmd0aC5vdXQ9MTQpDQpjYWxjIDwtIHJlcF9sZW4oYygiY2FsY2lmaWVkIiksIGxlbmd0aC5vdXQ9NykNCm5ha2VkIDwtIHJlcF9sZW4oYygibmFrZWQiKSwgbGVuZ3RoLm91dD03KQ0KbGl0aCA8LSByZXBfbGVuKGMoImxpdGgiKSwgbGVuZ3RoLm91dD03KQ0KZ3JvdXAgPC0gYyhjYWxjLCBuYWtlZCwgbGl0aCkNCnR1cmIgPC0gYXMuZGF0YS5mcmFtZShjYmluZChkaXNyYXRlLCBncm91cCkpDQoNCnR1cmIkcmFkIDwtIGNhc2Vfd2hlbigNCiAgICB0dXJiJGdyb3VwID09Im5ha2VkIiB+IDEuOEUtNiwNCiAgICB0dXJiJGdyb3VwID09ImNhbGNpZmllZCIgfiAyLjNFLTYsDQogICAgdHVyYiRncm91cCA9PSJsaXRoIiB+IDJFLTYsDQogICAgVFJVRSB+IGFzLm51bWVyaWModHVyYiRncm91cCkNCikNCiN0dXJiIDwtIG11dGF0ZSh0dXJiLCByYWQgPSBpZmVsc2UoZ3JvdXAgPT0gIm5ha2VkIiAsICAxLjhFLTYsICAyLjNFLTYpKSAjaW4gbQ0KDQp0dXJiJGRpc3JhdGUgPC0gYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIodHVyYiRkaXNyYXRlKSkNCg0KdHVyYiRLb2wgPC0gKCh2XjMvdHVyYiRkaXNyYXRlKV4wLjI1KSoxMDAgI0tvbG1vZ29yb3YgbGVuZ3RoIHNjYWxlIGluIGNtDQojZXZlcnl0aGluZyBpcyBiZWxvdyAxIGNtLCB1c2UgZXFuIDIgaW4gVEsgDQoNCnR1cmIkYmV0YV9kIDwtICg0LjIqcGkqKCh0dXJiJGRpc3JhdGUvKHYqMTAwXjIpKV4wLjUpKigoKHR1cmIkcmFkK1JlaHYpKjEwMCleMykpKjg2NDAwIA0KDQp0dXJiJGJldGFfSGVpZGkgPC0gKDAuNDIqcGkqKCh0dXJiJGRpc3JhdGUvKHYqMTAwXjIpKV4wLjUpKigoKHR1cmIkcmFkK1JlaHYpKjEwMCleMykpKjg2NDAwDQoNCiNjaGVjayBlbmNvdW50ZXJzDQoNCiN1c2UgVEssIGluIGNtMyBzDQp0dXJiJEVfdHVyYl9IViA8LSAodHVyYiRiZXRhX2QqaG9zdG51bSp2aXJudW0pICNFIGNhbGN1bGF0ZWQgd2l0aCBWaXJ1cyBhbmQgSG9zdCAoMTA6MSBNT0kpDQp0dXJiJEVfdHVyYl9WIDwtICh0dXJiJGJldGFfZCp2aXJudW0pICNFIGNhbGN1bGF0ZWQgd2l0aCB2aXJ1cyBvbmx5DQoNCiNicmVha3MgPC0gMTBeKC0xMDoxMCkNCiNtaW5vcl9icmVha3MgPC0gcmVwKDE6OSwgMjEpKigxMF5yZXAoLTEwOjEwLCBlYWNoPTkpKQ0KDQpnZ3Bsb3QoZGF0YSA9IHR1cmIsIGFlcyh4ID0gZGlzcmF0ZSwgeSA9IGJldGFfZCwgY29sb3I9Z3JvdXApKSArIGdlb21fcG9pbnQoc2l6ZSA9NSkgKw0KICBzY2FsZV95X2xvZzEwKA0KICAgICAgICBicmVha3MgPSBzY2FsZXM6OnRyYW5zX2JyZWFrcygibG9nMTAiLCBmdW5jdGlvbih4KSAxMF54LCBuPTQpLA0KICAgICAgICBsYWJlbHMgPSBzY2FsZXM6OnRyYW5zX2Zvcm1hdCgibG9nMTAiLCBzY2FsZXM6Om1hdGhfZm9ybWF0KDEwXi54KSkpICsNCiAgc2NhbGVfeF9sb2cxMCgNCiAgICAgICAgYnJlYWtzID0gc2NhbGVzOjp0cmFuc19icmVha3MoImxvZzEwIiwgZnVuY3Rpb24oeCkgMTBeeCwgbj00KSwNCiAgICAgICAgbGFiZWxzID0gc2NhbGVzOjp0cmFuc19mb3JtYXQoImxvZzEwIiwgc2NhbGVzOjptYXRoX2Zvcm1hdCgxMF4ueCkpKSArDQogIGFubm90YXRpb25fbG9ndGlja3MoKSArDQogIHRoZW1lX1B1YmxpY2F0aW9uKCkNCg0KbGlicmFyeShzY2FsZXMpDQoNCmdncGxvdChkYXRhID0gdHVyYiwgYWVzKHggPSBkaXNyYXRlLCB5ID0gRV90dXJiX1YsIGNvbG9yPWdyb3VwKSkgKyBnZW9tX3BvaW50KHNpemUgPTUpICsNCiAgIHNjYWxlX3lfbG9nMTAoDQogICAgICAgIGJyZWFrcyA9IHNjYWxlczo6dHJhbnNfYnJlYWtzKCJsb2cxMCIsIGZ1bmN0aW9uKHgpIDEwXngsIG49NCksDQogICAgICAgIGxhYmVscyA9IHNjYWxlczo6dHJhbnNfZm9ybWF0KCJsb2cxMCIsIHNjYWxlczo6bWF0aF9mb3JtYXQoMTBeLngpKSkgKw0KICBzY2FsZV94X2xvZzEwKA0KICAgICAgICBicmVha3MgPSBzY2FsZXM6OnRyYW5zX2JyZWFrcygibG9nMTAiLCBmdW5jdGlvbih4KSAxMF54LCBuPTQpLA0KICAgICAgICBsYWJlbHMgPSBzY2FsZXM6OnRyYW5zX2Zvcm1hdCgibG9nMTAiLCBzY2FsZXM6Om1hdGhfZm9ybWF0KDEwXi54KSkpICsNCiAgYW5ub3RhdGlvbl9sb2d0aWNrcygpKw0KICB0aGVtZV9QdWJsaWNhdGlvbigpDQoNCmBgYA0KDQphZGQgYmV0YSBrZXJuZWxzIGFuZCBwbG90DQoNCmBgYHtyfQ0KI2V4dHJhY3QgbWVhbiBiZXRhcyBmcm9tIFBJQ19uZXdkYXRhDQpiZXRhX0RTIDwtIHN1bW1hcnlTRSAoUElDX25ld2RhdGEsIG1lYXN1cmV2YXIgPSAiYmV0YS5wcmVkIiwgZ3JvdXB2YXJzID0gYygiZ3JvdXAiLCAiZ3JvdXAyIikpDQpsaXRoX0RTIDwtc3VtbWFyeVNFIChQSUNfbmV3ZGF0YSwgbWVhc3VyZXZhciA9ICJiZXRhLnByZWQubGl0aCIsIGdyb3VwdmFycyA9IGMoImdyb3VwIiwgImdyb3VwMiIpKQ0KDQpsaXRoX0RTJGdyb3VwMSA8LSBsaXRoX0RTJGdyb3VwDQpsaXRoX0RTJGdyb3VwIDwtICJsaXRoIg0KDQojc2VwYXJhdGUgZGF0YSBmcmFtZXMgZm9yIGhvc3QgYW5kIGxpdGhzDQoNCmFsbCA8LSBSZWR1Y2UoZnVuY3Rpb24oeCx5KSBtZXJnZSh4LHksYnk9Imdyb3VwIixhbGw9VFJVRSkgLA0KICAgICAgICAgICAgICBsaXN0KEJNLCBiZXRhX0RTLCB0dXJiICU+JSBmaWx0ZXIoZ3JvdXAgJWluJSBjKCJuYWtlZCIsICJjYWxjaWZpZWQiKSkpKQ0KDQoNCmFsbC5saXRocyAgPC0gUmVkdWNlKGZ1bmN0aW9uKHgseSkgbWVyZ2UoeCx5LGJ5PSJncm91cCIsYWxsPVRSVUUpICwNCiAgICAgICAgICAgICAgICAgICAgIGxpc3QobGl0aF9EUywgdHVyYiAlPiUgZmlsdGVyKGdyb3VwICVpbiUgYygibGl0aCIpKSkpDQoNCiNiZXRhX2QueD1CTSwgYmV0YS5wcmVkPURTLCBiZXRhcHJlZC5saXRoPSBiZXRhLnByZWQubGl0aCwgYmV0YV9kLnk9dHVyYg0KDQojcmVuYW1lIGJldGEucHJlZCB0byBiZXRhX3ByZWQgc28gSSBjYW4gdXNlIGdyZXAuIA0KI2FsbCA8LSByZW5hbWUgKGFsbCwgYygiYmV0YV9kLngiID0gImJldGFfQk0iLCAiYmV0YS5wcmVkIiA9ICJiZXRhX0RTIiwgImJldGFfZC55IiA9ICJiZXRhX3R1cmIiKSkNCg0KbGlicmFyeShkYXRhLnRhYmxlKQ0KTlQgPSBkYXRhLnRhYmxlKGFsbCwga2V5PSJncm91cDIueSIpDQphbGxiZXRhcyA9IE5UWywgbGlzdChncm91cD1ncm91cCwgZGlzcmF0ZT1kaXNyYXRlLCBiZXRhX0JNPWJldGFfZC54LCBiZXRhX0RTPWJldGEucHJlZCwgYmV0YV90dXJiID0gYmV0YV9kLnksIA0KICAgICAgICAgICAgICAgICAgICAgYmV0YV9CTV9EUyA9YmV0YV9kLnggKyBiZXRhLnByZWQsDQogICAgICAgICAgICAgICAgICAgICBiZXRhX0RTX3R1cmIgPSBiZXRhLnByZWQgKyBiZXRhX2QueSwNCiAgICAgICAgICAgICAgICAgICAgIGJldGFfRFNfdHVyYi5saXRoID0gYmV0YS5wcmVkLmxpdGggKyBiZXRhX2QueSwgDQogICAgICAgICAgICAgICAgICAgICBiZXRhX0JNX3R1cmIgPSBiZXRhX2QueCArIGJldGFfZC55LA0KICAgICAgICAgICAgICAgICAgICAgYmV0YV9hbGwgPSBiZXRhX2QueCArIGJldGFfZC55ICsgYmV0YS5wcmVkKSwgDQogICAgICAgICAgICAgIGJ5PWMoImdyb3VwMiIpXQ0KDQpnZ3Bsb3QoYWxsYmV0YXMsIGFlcyhkaXNyYXRlLCB5ID0gdmFsdWUsIGNvbG9yPWdyb3VwMikpICsgDQogIGdlb21fbGluZShhZXMoeSA9IGJldGFfRFNfdHVyYiwgbGluZXR5cGUgPSAiRFMrdHVyYiIpLCBzaXplPTEpICsgDQogIGdlb21fbGluZShhZXMoeSA9IGJldGFfYWxsLCBsaW5ldHlwZSA9ICJCTStEUyt0dXJiIiksIHNpemU9MSkrDQogIGdlb21fbGluZShhZXMoeSA9IGJldGFfdHVyYiwgbGluZXR5cGUgPSAidHVyYiIpLCBzaXplPTEpKw0KICBzY2FsZV95X2xvZzEwKA0KICAgICAgICBicmVha3MgPSBzY2FsZXM6OnRyYW5zX2JyZWFrcygibG9nMTAiLCBmdW5jdGlvbih4KSAxMF54LCBuPTQpLA0KICAgICAgICBsYWJlbHMgPSBzY2FsZXM6OnRyYW5zX2Zvcm1hdCgibG9nMTAiLCBzY2FsZXM6Om1hdGhfZm9ybWF0KDEwXi54KSkpICsNCiAgc2NhbGVfeF9sb2cxMCgNCiAgICAgICAgYnJlYWtzID0gc2NhbGVzOjp0cmFuc19icmVha3MoImxvZzEwIiwgZnVuY3Rpb24oeCkgMTBeeCwgbj03KSwNCiAgICAgICAgbGFiZWxzID0gc2NhbGVzOjp0cmFuc19mb3JtYXQoImxvZzEwIiwgc2NhbGVzOjptYXRoX2Zvcm1hdCgxMF4ueCkpKSArDQogIGFubm90YXRpb25fbG9ndGlja3MoKSsNCiAgdGhlbWVfUHVibGljYXRpb24oKQ0KDQojZW5jb3VudGVycw0KDQojbWVsdCBkYXRhDQoNCmFsbGJldGFzLm1lbHQgPC0gbWVsdCAoYWxsYmV0YXMsIGlkLnZhcnMgPSBjKCJncm91cDIiLCAiZ3JvdXAiLCAiZGlzcmF0ZSIpLCB2YWx1ZS5uYW1lID0gImJldGFfZCIsIA0KICAgICAgICAgICAgICAgICAgICAgICB2YXJpYWJsZS5uYW1lID0gImJldGFrZXJuZWwiKQ0KDQphbGxiZXRhcy5tZWx0JGdyb3VwMiA8LSBmYWN0b3IgKGFsbGJldGFzLm1lbHQkZ3JvdXAyLGxldmVscz0gYygibmFrZWRfYm91eWFudCIsICJuYWtlZC9jYWxjaWZpZWQgdW5jZXJ0YWluIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibW9kZXJhdGVseSBjYWxjaWZpZWQiLCAic3Ryb25nbHkgY2FsY2lmaWVkIiksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygibmFrZWQiLCAibmFrZWQvY2FsY2lmaWVkIHVuY2VydGFpbiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibW9kZXJhdGVseSBjYWxjaWZpZWQiLCAic3Ryb25nbHkgY2FsY2lmaWVkIikpDQoNCmFsbGJldGFzLm1lbHQkRV9WIDwtIGFsbGJldGFzLm1lbHQkYmV0YV9kKnZpcm51bQ0KDQpnZ3Bsb3QoYWxsYmV0YXMubWVsdCwgYWVzKGRpc3JhdGUsIHkgPSBFX1YsIGNvbG9yPWdyb3VwMikpICsgDQogIGdlb21fbGluZShzaXplPTEpKw0KICBzY2FsZV95X2xvZzEwKA0KICAgICAgICBicmVha3MgPSBzY2FsZXM6OnRyYW5zX2JyZWFrcygibG9nMTAiLCBmdW5jdGlvbih4KSAxMF54LCBuPTQpLA0KICAgICAgICBsYWJlbHMgPSBzY2FsZXM6OnRyYW5zX2Zvcm1hdCgibG9nMTAiLCBzY2FsZXM6Om1hdGhfZm9ybWF0KDEwXi54KSkpICsNCiAgc2NhbGVfeF9sb2cxMCgNCiAgICAgICAgYnJlYWtzID0gc2NhbGVzOjp0cmFuc19icmVha3MoImxvZzEwIiwgZnVuY3Rpb24oeCkgMTBeeCwgbj03KSwNCiAgICAgICAgbGFiZWxzID0gc2NhbGVzOjp0cmFuc19mb3JtYXQoImxvZzEwIiwgc2NhbGVzOjptYXRoX2Zvcm1hdCgxMF4ueCkpKSArDQogIGFubm90YXRpb25fbG9ndGlja3MoKSArIGZhY2V0X2dyaWQofmJldGFrZXJuZWwpDQoNCiNzdWJzZXQgZGF0YQ0KDQpncmFwaDEgPC0gc3Vic2V0KGFsbGJldGFzLm1lbHQsIGJldGFrZXJuZWwgJWluJSBjICgiYmV0YV9CTSIsICJiZXRhX0RTIiwgImJldGFfQk1fRFMiKSkNCmdyYXBoMiA8LSBzdWJzZXQoYWxsYmV0YXMubWVsdCwgYmV0YWtlcm5lbCAlaW4lIGMgKCJiZXRhX3R1cmIiLCAiYmV0YV9EU190dXJiIiwgImJldGFfQk1fdHVyYiIsICJiZXRhX2FsbCIpKQ0KDQpnZ3Bsb3QoZ3JhcGgxLCBhZXMoZ3JvdXAyLCB5ID0gRV9WLCBjb2xvcj1iZXRha2VybmVsKSkgKyANCiAgZ2VvbV9qaXR0ZXIoc2l6ZT01KSsNCiAgc2NhbGVfeV9sb2cxMCgNCiAgICAgICAgYnJlYWtzID0gc2NhbGVzOjp0cmFuc19icmVha3MoImxvZzEwIiwgZnVuY3Rpb24oeCkgMTBeeCwgbj00KSwNCiAgICAgICAgbGFiZWxzID0gc2NhbGVzOjp0cmFuc19mb3JtYXQoImxvZzEwIiwgc2NhbGVzOjptYXRoX2Zvcm1hdCgxMF4ueCkpKSArDQogIGFubm90YXRpb25fbG9ndGlja3Moc2lkZXMgPSAibCIpKw0KICB0aGVtZV9QdWJsaWNhdGlvbigpDQoNCmdyYXBoMS5zdW0gPC0gc3VtbWFyeVNFIChncmFwaDEsIG1lYXN1cmV2YXIgPSAiRV9WIiwgZ3JvdXB2YXJzID0gYygiYmV0YWtlcm5lbCIsICJncm91cDIiKSkNCg0KZ2dwbG90KGdyYXBoMS5zdW0sIGFlcyhncm91cDIsIHkgPSBFX1YsIGNvbG9yPWJldGFrZXJuZWwpKSArIA0KICBnZW9tX3BvaW50KHNpemU9NSwgIHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKDAuMikpKw0KICBzY2FsZV95X2xvZzEwKA0KICAgICAgICBicmVha3MgPSBzY2FsZXM6OnRyYW5zX2JyZWFrcygibG9nMTAiLCBmdW5jdGlvbih4KSAxMF54LCBuPTQpLA0KICAgICAgICBsYWJlbHMgPSBzY2FsZXM6OnRyYW5zX2Zvcm1hdCgibG9nMTAiLCBzY2FsZXM6Om1hdGhfZm9ybWF0KDEwXi54KSkpICsNCiAgYW5ub3RhdGlvbl9sb2d0aWNrcyhzaWRlcyA9ICJsIikrDQogIHRoZW1lX1B1YmxpY2F0aW9uKCkNCg0KZ2dwbG90KGRhdGE9YWxsYmV0YXMubWVsdCAlPiUgZmlsdGVyKGJldGFrZXJuZWwgJWluJSBjKCJiZXRhX3R1cmIiLCAiYmV0YV9hbGwiKSksIA0KICAgICAgIGFlcyh4PWRpc3JhdGUseSA9IEVfViwgY29sb3I9Z3JvdXAyLCBsaW5ldHlwZT1iZXRha2VybmVsKSkgKyANCiAgZ2VvbV9saW5lKHNpemU9MSwgcG9zaXRpb249cG9zaXRpb25faml0dGVyKHc9MC4wMiwgaD0wKSkrDQogICBzY2FsZV95X2xvZzEwKA0KICAgICAgICBicmVha3MgPSBzY2FsZXM6OnRyYW5zX2JyZWFrcygibG9nMTAiLCBmdW5jdGlvbih4KSAxMF54LCBuPTQpLA0KICAgICAgICBsYWJlbHMgPSBzY2FsZXM6OnRyYW5zX2Zvcm1hdCgibG9nMTAiLCBzY2FsZXM6Om1hdGhfZm9ybWF0KDEwXi54KSkpICsNCiAgc2NhbGVfeF9sb2cxMCgNCiAgICAgICAgYnJlYWtzID0gc2NhbGVzOjp0cmFuc19icmVha3MoImxvZzEwIiwgZnVuY3Rpb24oeCkgMTBeeCwgbj03KSwNCiAgICAgICAgbGFiZWxzID0gc2NhbGVzOjp0cmFuc19mb3JtYXQoImxvZzEwIiwgc2NhbGVzOjptYXRoX2Zvcm1hdCgxMF4ueCkpKSArDQogIGFubm90YXRpb25fbG9ndGlja3MoKSsNCiAgdGhlbWVfUHVibGljYXRpb24oKQ0KDQpnZ3Bsb3QoZGF0YT1hbGxiZXRhcy5tZWx0ICU+JSBmaWx0ZXIoYmV0YWtlcm5lbCAlaW4lIGMoImJldGFfYWxsIikpLCANCiAgICAgICBhZXMoeD1kaXNyYXRlLHkgPSBFX1YsIGNvbG9yPWdyb3VwMikpICsgDQogIGdlb21fbGluZShzaXplPTEsIHBvc2l0aW9uPXBvc2l0aW9uX2ppdHRlcih3PTAuMDIsIGg9MCkpKw0KICAgc2NhbGVfeV9sb2cxMCgNCiAgICAgICAgYnJlYWtzID0gc2NhbGVzOjp0cmFuc19icmVha3MoImxvZzEwIiwgZnVuY3Rpb24oeCkgMTBeeCwgbj0yKSwNCiAgICAgICAgbGFiZWxzID0gc2NhbGVzOjp0cmFuc19mb3JtYXQoImxvZzEwIiwgc2NhbGVzOjptYXRoX2Zvcm1hdCgxMF4ueCkpKSArDQogIHNjYWxlX3hfbG9nMTAoDQogICAgICAgIGJyZWFrcyA9IHNjYWxlczo6dHJhbnNfYnJlYWtzKCJsb2cxMCIsIGZ1bmN0aW9uKHgpIDEwXngsIG49NyksDQogICAgICAgIGxhYmVscyA9IHNjYWxlczo6dHJhbnNfZm9ybWF0KCJsb2cxMCIsIHNjYWxlczo6bWF0aF9mb3JtYXQoMTBeLngpKSkgKw0KICBhbm5vdGF0aW9uX2xvZ3RpY2tzKCkrDQogIHRoZW1lX1B1YmxpY2F0aW9uKCkNCg0KYGBgDQoNCg==